package com.hdax.dm.service;

import com.hdax.dm.common.vo.item.ItemListVo;
import com.hdax.dm.dto.CommonResponse;
import com.hdax.dm.dto.DtoUtil;
import com.hdax.dm.dto.PageDto;
import com.hdax.dm.dto.item.FloorItemDto;
import com.hdax.dm.dto.item.ItemListDto;
import com.hdax.dm.entity.base.DmImage;
import com.hdax.dm.entity.item.DmItem;
import com.hdax.dm.feign.base.DmAreaFeign;
import com.hdax.dm.feign.base.DmImageFeign;
import com.hdax.dm.utils.MokeImage;
import org.checkerframework.checker.units.qual.A;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.awt.geom.Area;
import java.util.*;

@Service
public class DmItemListService {

    @Autowired
    private DmAreaFeign areaFeign;
    @Autowired
    private ElasticsearchRestTemplate esTemplate;
    @Autowired
    private DmImageFeign imageFeign;


    //返回所有城市集合
    public CommonResponse<List<Area>> querycity(){
        return DtoUtil.returnSuccess(areaFeign.getArea());
    }

    //es检索可能喜欢
    public CommonResponse<List<FloorItemDto>> guesslike(Long typeid){
        List<FloorItemDto> floorItems = new ArrayList<>();
        //复合查询  查询条件构造器
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //精确查询（不评分） 如果typeid为空，则默认为1，如果小于8，则默认查询两级分类
        if (typeid==0){
            typeid = 1L;
        }
        if (typeid<=8){
            boolQueryBuilder.must(QueryBuilders.termQuery("itemtype1id",typeid));
        }else {
            boolQueryBuilder.must(QueryBuilders.termQuery("itemtype2id",typeid));
        }

        //封装查询条件
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                //分页查询
                .withPageable(PageRequest.of((int) (1-1),6))
                .build();
        //SearchHits 类似 ResultSet
        SearchHits<ItemListDto> searchHits = esTemplate.search(query,ItemListDto.class);
        //List<SearchHit>==>List<DmItem>    类似于拷贝属性
        searchHits.getSearchHits().forEach(searchHit->{
            ItemListDto item = searchHit.getContent();
            //获取图片
            DmImage dmImage = imageFeign.getImage(2L,1L,item.getId());
            item.setImgUrl(dmImage==null? MokeImage.getImage(1) :dmImage.getImgUrl());
            FloorItemDto floorItemDto = new FloorItemDto();
            BeanUtils.copyProperties(item,floorItemDto);
            floorItemDto.setStartDate(item.getStartTime());
            floorItemDto.setEndDate(item.getEndTime());
            floorItems.add(floorItemDto);
        });
        return DtoUtil.returnSuccess(floorItems);
    }

    //es检索商品列表
    public CommonResponse<PageDto<ItemListDto>> querygoodsinfos(ItemListVo itemListVo){
        //复合查询  查询条件构造器
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //模糊查询
        if(itemListVo.getKeyword()!=null&&!itemListVo.getKeyword().equals("")) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("itemname", itemListVo.getKeyword()));
            //加分
            boolQueryBuilder.should(QueryBuilders.matchQuery("abstractmessage",itemListVo.getKeyword()));
        }
        //精确查询（不评分）
        if (itemListVo.getItemTypeId1()!=0&&itemListVo.getItemTypeId1()!=null){
            boolQueryBuilder.must(QueryBuilders.termQuery("itemtype1id",itemListVo.getItemTypeId1()));
        }
        if (itemListVo.getItemTypeId2()!=0&&itemListVo.getItemTypeId2()!=null){
            boolQueryBuilder.must(QueryBuilders.termQuery("itemtype2id",itemListVo.getItemTypeId2()));
        }
        if (itemListVo.getAreaId()!=0&&itemListVo.getAreaId()!=null){
            boolQueryBuilder.must(QueryBuilders.termQuery("areaid",itemListVo.getAreaId()));
        }
        //范围查询 range lt gt lte gte
        if (itemListVo.getEndTime()!=null&&!itemListVo.getEndTime().equals("")&&itemListVo.getStartTime()!=null&&!itemListVo.getStartTime().equals("")){
            Calendar   calendar = new GregorianCalendar();
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("starttime");
            //如果起始时间和结束时间相等，则进行起始时间与起始时间+1天的范围查询
            if (itemListVo.getStartTime().equals(itemListVo.getEndTime())){
                calendar.setTime(itemListVo.getStartTime());
                calendar.add(calendar.DATE,1); //把日期往后增加一天,整数  往后推,负数往前移动
                boolQueryBuilder.must(rangeQueryBuilder.gte(itemListVo.getStartTime()).lte(calendar.getTime()));
            //如果起始时间和结束时间不相等，则进行起始时间与结束时间的范围查询
            }else {
                boolQueryBuilder.must(rangeQueryBuilder.gte(itemListVo.getStartTime()).lte(itemListVo.getEndTime()));
            }
        }

        //排序
        SortBuilder sortBuilder = null;
        //最近上架（createtime 降序）
        if (itemListVo.getSort().equals("recentSell")){
            sortBuilder = SortBuilders.fieldSort("createdtime").order(SortOrder.DESC);
            //最近开场(starttime 升序)
        }else if (itemListVo.getSort().equals("recentShow")){
            sortBuilder = SortBuilders.fieldSort("starttime").order(SortOrder.ASC);
            //热门推荐(isbanner=1)
        }else {
            boolQueryBuilder.must(QueryBuilders.termQuery("isbanner","1"));
        }
        //封装查询条件
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        searchQueryBuilder.withQuery(boolQueryBuilder)
                //高亮显示关键字
                .withHighlightFields(
                        new HighlightBuilder.Field("itemname"),
                        new HighlightBuilder.Field("abstractmessage")
                ).withHighlightBuilder(
                        new HighlightBuilder()
                                .preTags("<span style=\"color:red\">")
                                .postTags("</span>")
                ).withPageable(PageRequest.of((int) (itemListVo.getCurrentPage()-1),itemListVo.getPageSize().intValue()));
                //分页查询

        //如果排序对象不为空，则加入排序条件
        if (sortBuilder!=null){
            searchQueryBuilder.withSort(sortBuilder);
        }

        NativeSearchQuery query1 = searchQueryBuilder.build();

        //SearchHits 类似 ResultSet
        SearchHits<ItemListDto> searchHits = esTemplate.search(query1,ItemListDto.class);
        List<ItemListDto> list = new ArrayList<>();

        //List<SearchHit>==>List<DmItem>    类似于拷贝属性
        searchHits.getSearchHits().forEach(searchHit->{
            //存储了所有设置过高亮字段的内容
            Map<String, List<String>> map = searchHit.getHighlightFields();

            //getContent()获取实体属性
            ItemListDto item = searchHit.getContent();
            //使用高亮字段替换原始字段
            if (map.get("itemName")!=null){
                item.setItemName(map.get("itemName").get(0));
            }
            if (map.get("abstractMessage")!=null){
                item.setAbstractMessage(map.get("abstractMessage").get(0));
            }
            //获取图片
            DmImage dmImage = imageFeign.getImage(2L,1L,item.getId());
            item.setImgUrl(dmImage==null?MokeImage.getImage(1):dmImage.getImgUrl());
            list.add(item);
        });

        //封装PageDto对象   页数小于1则默认为1
        PageDto<ItemListDto> pageDto = new PageDto(itemListVo.getCurrentPage(),
                itemListVo.getPageSize(), searchHits.getTotalHits(),
                list.size()/itemListVo.getPageSize()<1?1:list.size()/itemListVo.getPageSize(),list);
        return DtoUtil.returnSuccess(pageDto);
    }
}
